import random
from django_redis import get_redis_connection
from rest_framework_simplejwt.views import TokenObtainPairView
from .serializers import CustomTokenObtainSerializer
from rest_framework.generics import CreateAPIView
from .models import User
from .serializers import UserModelSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from skylark_api.settings import constants
from mycelery.sms.tasks import send_sms
import logging

logger = logging.getLogger("django")

class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class = CustomTokenObtainSerializer

class UserAPIView(CreateAPIView):
    """用户信息视图"""
    queryset = User.objects.all()
    serializer_class = UserModelSerializer


# 短信发送
"""
1.判断手机号码是否在60秒内发送过短信
2.生成短信验证码
3.保存短信验证码到redis
4.调用短信SDK，发送短信
5.获取结果
"""


class SMSAPIView(APIView):
    # sms短信验证码获取，根据手机号码 sms/13080554121
    def get(self, request, phone):
        # 1.判断手机号码是否在60秒内发送过短信
        # 链接到redis对象
        redis_conn = get_redis_connection("sms_code")
        # phone_13080554121
        ret = redis_conn.get(f'phone_{phone}')
        if ret is not None:
            return Response({'message': "对不起，60秒内已经发送过短信，请耐心等待"}, status=status.HTTP_400_BAD_REQUEST)

        # 2.生成短信验证码
        # 生成6位验证码
        sms_code = "%06d" % random.randint(1, 999999)
        sms_code = sms_code[:random.randint(4, 6)]

        # 3.保存短信验证码到redis
        #         redis_conn.setex() 设置键值对和过期时间的方法
        """
        setex(key, time, value)
        :key 键名
        :value 值
        : time 过期时间(/秒)
        :作用 存储临时数据
        短信验证码
        会话令牌
        缓存数据
        """

        # 使用事务确保操作的原子性
        pipe = redis_conn.pipeline()
        pipe.multi()  # 开启事务模式
        pipe.setex(f"sms_{phone}", constants.SMS_EXPIRE_TIME, sms_code)
        pipe.setex(f"phone_{phone}", constants.SMS_INTERVAL_TIME, "_")
        pipe.execute()  # 提交事务，执行所有命令

        # 通过celery异步发送短信
        # 是apply_async()的快捷方式，用于将任务发布到消息队列中，由celery worker异步执行
        # 4. 调用 Celery 任务发送短信
        try:
            # 调用 Celery 异步任务
            send_sms.delay(phone, sms_code)
            logger.info(f"短信发送任务已提交！手机号：{phone}，验证码：{sms_code}")
            return Response({"message": "发送短信成功！"})
        except Exception as e:
            logger.error(f"短信发送任务异常！手机号：{phone}，异常信息：{str(e)}")
            return Response({"message": "发送短信失败！"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
